package com.atguigu.service.impl;

import com.atguigu.service.CouponService;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;

/**
 * @Author: shenhao
 * @CreatTime: 2024/10/25 21:41
 * @Version: 1.0
 * explain index access abort discard Encryption
 */
@Service
//Autowired members must be defined in valid Spring bean (@Component|@Service|…)，
// 它的含义就是：自动注入对象必须定义在有效的spring bean内，也就是说只有本身作为bean的类才能注入其他对象。
public class CouponServiceImpl implements CouponService {
    //下发优惠卷数量
    public static final Integer COUPON_NUMBER = 50;
    @Autowired
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    /**
     * 下发50条优惠卷
     */
    @Override
    public void batchTaskAction() {
        //1 模拟要下发的50条优惠卷，上游系统给我们的下发优惠卷源头
        List<String> coupons = new ArrayList<>(COUPON_NUMBER);
        for (int i = 1; i <= COUPON_NUMBER; i++) {
            coupons.add("优惠卷--" + i);
        }
        //2 创建CountDownLatch,构造器参数为任务数量 计数器倒计时
        CountDownLatch countDownLatch = new CountDownLatch(coupons.size());
        long start = System.currentTimeMillis();
        try {
            for (String coupon : coupons) {
                threadPoolTaskExecutor.execute(() -> {
                    try {
                        //4 交个线程池处理的下发业务逻辑，可以提出成一个方法
                        System.out.println(String.format("[%s]发送成功",coupon));
                    } catch (Exception e) {
                        e.printStackTrace();
                    }finally {
                        //5 发送一个少一个任务，计数减少一个
                        countDownLatch.countDown();
                    }
                });
            }
            //6 阻塞当前发送完毕后，方法才能继续向下走
            countDownLatch.await();
        } catch (Exception e) {
            e.printStackTrace();
        }
        long end = System.currentTimeMillis();
        System.out.println("--------任务处理完毕costTime:" + (end - start)+"ms");
    }
}
